home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Tcl-Tk 8.0 / Pre-installed version / tk8.0 / mac / tkMacHLEvents.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-15  |  9.2 KB  |  382 lines  |  [TEXT/CWIE]

  1. /* 
  2.  * tkMacHLEvents.c --
  3.  *
  4.  *    Implements high level event support for the Macintosh.  Currently, 
  5.  *    the only event that really does anything is the Quit event.
  6.  *
  7.  * Copyright (c) 1995-1996 Sun Microsystems, Inc.
  8.  *
  9.  * See the file "license.terms" for information on usage and redistribution
  10.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  *
  12.  * SCCS: @(#) tkMacHLEvents.c 1.18 96/12/17 19:48:36
  13.  */
  14.  
  15. #include "tcl.h"
  16. #include "tclMacInt.h"
  17. #include "tkMacInt.h"
  18.  
  19. #include <Aliases.h>
  20. #include <AppleEvents.h>
  21. #include <SegLoad.h>
  22. #include <ToolUtils.h>
  23.  
  24. static pascal OSErr QuitHandler _ANSI_ARGS_((AppleEvent* event,
  25.     AppleEvent* reply, long refcon));
  26. static pascal OSErr OappHandler _ANSI_ARGS_((AppleEvent* event,
  27.     AppleEvent* reply, long refcon));
  28. static pascal OSErr OdocHandler _ANSI_ARGS_((AppleEvent* event,
  29.     AppleEvent* reply, long refcon));
  30. static pascal OSErr PrintHandler _ANSI_ARGS_((AppleEvent* event,
  31.     AppleEvent* reply, long refcon));
  32. static pascal OSErr ScriptHandler _ANSI_ARGS_((AppleEvent* event,
  33.     AppleEvent* reply, long refcon));
  34. static int MissedAnyParameters _ANSI_ARGS_((AppleEvent *theEvent));
  35.  
  36.  
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  * TkMacInitAppleEvents --
  41.  *
  42.  *    Initilize the Apple Events on the Macintosh.  This registers the
  43.  *    core event handlers.
  44.  *
  45.  * Results:
  46.  *    None.
  47.  *
  48.  * Side effects:
  49.  *    None.
  50.  *
  51.  *----------------------------------------------------------------------
  52.  */
  53.  
  54. void 
  55. TkMacInitAppleEvents(
  56.     Tcl_Interp *interp)        /* Interp to handle basic events. */
  57. {
  58.     OSErr err;
  59.     AEEventHandlerUPP    OappHandlerUPP, OdocHandlerUPP,
  60.     PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP;
  61.     
  62.     /*
  63.      * Install event handlers for the core apple events.
  64.      */
  65.     QuitHandlerUPP = NewAEEventHandlerProc(QuitHandler);
  66.     err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  67.         QuitHandlerUPP, (long) interp, false);
  68.  
  69.     OappHandlerUPP = NewAEEventHandlerProc(OappHandler);
  70.     err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  71.         OappHandlerUPP, (long) interp, false);
  72.  
  73.     OdocHandlerUPP = NewAEEventHandlerProc(OdocHandler);
  74.     err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  75.         OdocHandlerUPP, (long) interp, false);
  76.  
  77.     PrintHandlerUPP = NewAEEventHandlerProc(PrintHandler);
  78.     err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  79.         PrintHandlerUPP, (long) interp, false);
  80.  
  81.     if (interp != NULL) {
  82.     ScriptHandlerUPP = NewAEEventHandlerProc(ScriptHandler);
  83.     err = AEInstallEventHandler('misc', 'dosc',
  84.         ScriptHandlerUPP, (long) interp, false);
  85.     }
  86. }
  87.  
  88. /*
  89.  *----------------------------------------------------------------------
  90.  *
  91.  * TkMacDoHLEvent --
  92.  *
  93.  *    Dispatch incomming highlevel events.
  94.  *
  95.  * Results:
  96.  *    None.
  97.  *
  98.  * Side effects:
  99.  *    Depends on the incoming event.
  100.  *
  101.  *----------------------------------------------------------------------
  102.  */
  103.  
  104. void
  105. TkMacDoHLEvent(
  106.     EventRecord *theEvent)
  107. {
  108.     AEProcessAppleEvent(theEvent);
  109.  
  110.     return;
  111. }
  112.  
  113. /*
  114.  *----------------------------------------------------------------------
  115.  *
  116.  * QuitHandler, OappHandler, etc. --
  117.  *
  118.  *    These are the core Apple event handlers.  Only the Quit event does
  119.  *    anything interesting.
  120.  *
  121.  * Results:
  122.  *    None.
  123.  *
  124.  * Side effects:
  125.  *    None.
  126.  *
  127.  *----------------------------------------------------------------------
  128.  */
  129.  
  130. static pascal OSErr
  131. QuitHandler(
  132.     AppleEvent *theAppleEvent,
  133.     AppleEvent *reply,
  134.     long handlerRefcon)
  135. {
  136.     Tcl_Interp     *interp = (Tcl_Interp *) handlerRefcon;
  137.     
  138.     /*
  139.      * Call the exit command.  However, if it doesn't quit - quit anyway.
  140.      */
  141.     if (interp != NULL) {
  142.     Tcl_GlobalEval(interp, "exit");
  143.     }
  144.     Tcl_Exit(0);
  145.     return noErr;
  146. }
  147.  
  148. static pascal OSErr
  149. OappHandler(
  150.     AppleEvent *theAppleEvent,
  151.     AppleEvent *reply,
  152.     long handlerRefcon)
  153. {
  154.     return noErr;
  155. }
  156.  
  157. static pascal OSErr
  158. OdocHandler(
  159.     AppleEvent *theAppleEvent,
  160.     AppleEvent *reply,
  161.     long handlerRefcon)
  162. {
  163.     Tcl_Interp     *interp = (Tcl_Interp *) handlerRefcon;
  164.     AEDescList fileSpecList;
  165.     FSSpec file;
  166.     OSErr err;
  167.     DescType type;
  168.     Size actual;
  169.     long count;
  170.     AEKeyword keyword;
  171.     long index;
  172.     Tcl_DString command;
  173.     Tcl_DString pathName;
  174.     Tcl_CmdInfo dummy;
  175.  
  176.     /*
  177.      * Don't bother if we don't have an interp or
  178.      * the open document procedure doesn't exist.
  179.      */
  180.     if ((interp == NULL) || 
  181.         (Tcl_GetCommandInfo(interp, "tkOpenDocument", &dummy)) == 0) {
  182.         return noErr;
  183.     }
  184.     
  185.     /*
  186.      * If we get any errors wil retrieving our parameters
  187.      * we just return with no error.
  188.      */
  189.     err = AEGetParamDesc(theAppleEvent, keyDirectObject,
  190.         typeAEList, &fileSpecList);
  191.     if (err != noErr) {
  192.     return noErr;
  193.     }
  194.  
  195.     err = MissedAnyParameters(theAppleEvent);
  196.     if (err != noErr) {
  197.     return noErr;
  198.     }
  199.  
  200.     err = AECountItems(&fileSpecList, &count);
  201.     if (err != noErr) {
  202.     return noErr;
  203.     }
  204.  
  205.     Tcl_DStringInit(&command);
  206.     Tcl_DStringInit(&pathName);
  207.     Tcl_DStringAppend(&command, "tkOpenDocument", -1);
  208.     for (index = 1; index <= count; index++) {
  209.     int length;
  210.     Handle fullPath;
  211.     
  212.     Tcl_DStringSetLength(&pathName, 0);
  213.     err = AEGetNthPtr(&fileSpecList, index, typeFSS,
  214.         &keyword, &type, (Ptr) &file, sizeof(FSSpec), &actual);
  215.     if ( err != noErr ) {
  216.         continue;
  217.     }
  218.  
  219.     err = FSpPathFromLocation(&file, &length, &fullPath);
  220.     HLock(fullPath);
  221.     Tcl_DStringAppend(&pathName, *fullPath, length);
  222.     HUnlock(fullPath);
  223.     DisposeHandle(fullPath);
  224.  
  225.     Tcl_DStringAppendElement(&command, pathName.string);
  226.     }
  227.     
  228.     Tcl_GlobalEval(interp, command.string);
  229.  
  230.     Tcl_DStringFree(&command);
  231.     Tcl_DStringFree(&pathName);
  232.     return noErr;
  233. }
  234.  
  235. static pascal OSErr
  236. PrintHandler(
  237.     AppleEvent *theAppleEvent,
  238.     AppleEvent *reply,
  239.     long handlerRefcon)
  240. {
  241.     return noErr;
  242. }
  243.  
  244. /*
  245.  *----------------------------------------------------------------------
  246.  *
  247.  * DoScriptHandler --
  248.  *
  249.  *    This handler process the do script event.  
  250.  *
  251.  * Results:
  252.  *    Scedules the given event to be processed.
  253.  *
  254.  * Side effects:
  255.  *    None.
  256.  *
  257.  *----------------------------------------------------------------------
  258.  */
  259.  
  260. static pascal OSErr 
  261. ScriptHandler(
  262.     AppleEvent *theAppleEvent,
  263.     AppleEvent *reply,
  264.     long handlerRefcon)
  265. {
  266.     OSErr theErr;
  267.     AEDescList theDesc;
  268.     int tclErr = -1;
  269.     Tcl_Interp *interp;
  270.     char errString[128];
  271.  
  272.     interp = (Tcl_Interp *) handlerRefcon;
  273.  
  274.     /*
  275.      * The do script event receives one parameter that should be data or a file.
  276.      */
  277.     theErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard,
  278.         &theDesc);
  279.     if (theErr != noErr) {
  280.     sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", theErr);
  281.     theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString,
  282.         strlen(errString));
  283.     } else if (MissedAnyParameters(theAppleEvent)) {
  284.     sprintf(errString, "AEDoScriptHandler: extra parameters");
  285.     AEPutParamPtr(reply, keyErrorString, typeChar, errString,
  286.         strlen(errString));
  287.     theErr = -1771;
  288.     } else {
  289.     if (theDesc.descriptorType == (DescType)'TEXT') {
  290.         short length, i;
  291.         
  292.         length = GetHandleSize(theDesc.dataHandle);
  293.         SetHandleSize(theDesc.dataHandle, length + 1);
  294.         *(*theDesc.dataHandle + length) = '\0';
  295.         for (i=0; i<length; i++) {
  296.         if ((*theDesc.dataHandle)[i] == '\r') {
  297.             (*theDesc.dataHandle)[i] = '\n';
  298.         }
  299.         }
  300.  
  301.         HLock(theDesc.dataHandle);
  302.         tclErr = Tcl_GlobalEval(interp, *theDesc.dataHandle);
  303.         HUnlock(theDesc.dataHandle);
  304.     } else if (theDesc.descriptorType == (DescType)'alis') {
  305.         Boolean dummy;
  306.         FSSpec theFSS;
  307.         Handle fullPath;
  308.         int length;
  309.         
  310.         theErr = ResolveAlias(NULL, (AliasHandle)theDesc.dataHandle,
  311.             &theFSS, &dummy);
  312.         if (theErr == noErr) {
  313.         FSpPathFromLocation(&theFSS, &length, &fullPath);
  314.         HLock(fullPath);
  315.         Tcl_EvalFile(interp, *fullPath);
  316.         HUnlock(fullPath);
  317.         DisposeHandle(fullPath);
  318.         } else {
  319.         sprintf(errString, "AEDoScriptHandler: file not found");
  320.         AEPutParamPtr(reply, keyErrorString, typeChar,
  321.             errString, strlen(errString));
  322.         }
  323.     } else {
  324.         sprintf(errString,
  325.             "AEDoScriptHandler: invalid script type '%-4.4s', must be 'alis' or 'TEXT'",
  326.             &theDesc.descriptorType);
  327.         AEPutParamPtr(reply, keyErrorString, typeChar,
  328.             errString, strlen(errString));
  329.         theErr = -1770;
  330.     }
  331.     }
  332.  
  333.     /*
  334.      * If we actually go to run Tcl code - put the result in the reply.
  335.      */
  336.     if (tclErr >= 0) {
  337.     if (tclErr == TCL_OK)  {
  338.         AEPutParamPtr(reply, keyDirectObject, typeChar,
  339.         interp->result, strlen(interp->result));
  340.     } else {
  341.         AEPutParamPtr(reply, keyErrorString, typeChar,
  342.         interp->result, strlen(interp->result));
  343.         AEPutParamPtr(reply, keyErrorNumber, typeInteger,
  344.         (Ptr) &tclErr, sizeof(int));
  345.     }
  346.     }
  347.     
  348.     AEDisposeDesc(&theDesc);
  349.  
  350.     return theErr;
  351. }
  352.  
  353. /*
  354.  *----------------------------------------------------------------------
  355.  *
  356.  * MissedAnyParameters --
  357.  *
  358.  *    Checks to see if parameters are still left in the event.  
  359.  *
  360.  * Results:
  361.  *    True or false.
  362.  *
  363.  * Side effects:
  364.  *    None.
  365.  *
  366.  *----------------------------------------------------------------------
  367.  */
  368.  
  369. static int 
  370. MissedAnyParameters(
  371.     AppleEvent *theEvent)
  372. {
  373.    DescType returnedType;
  374.    Size actualSize;
  375.    OSErr err;
  376.  
  377.    err = AEGetAttributePtr(theEvent, keyMissedKeywordAttr, typeWildCard, 
  378.            &returnedType, NULL, 0, &actualSize);
  379.    
  380.    return (err != errAEDescNotFound);
  381. }
  382.